from datetime import datetime

from sqlalchemy import event, text, ForeignKey, ForeignKeyConstraint
from sqlalchemy.orm import relationship
from extension import db, login_manager
from flask_login import UserMixin


class User(UserMixin, db.Model):
    __tablename__ = 'users'

    student_id = db.Column(db.String(20), nullable=False, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    password = db.Column(db.String(200), nullable=False)
    college = db.Column(db.String(64), nullable=False)
    grade = db.Column(db.Integer, nullable=False)
    role = db.Column(db.String(20), nullable=False)
    email = db.Column(db.String(100), nullable=True)

    # Relationships
    #submissions = relationship('SubmissionResource', backref='user', lazy=True)
    ai_chats = relationship('AIChat', backref='user', lazy=True)
    exam_records = relationship('ExamRecord', backref='user', lazy=True)

    def __init__(self, student_id, name, password, college, grade, role, email):
        self.student_id = student_id
        self.name = name
        self.password = password
        self.college = college
        self.grade = grade
        self.role = role
        self.email = email

    def set_password(self, password):
        self.password = password

    def set_college(self, college):
        self.college = college

    def set_grade(self, grade):
        self.grade = grade

    def is_teacher(self) -> bool:
        return self.role == "teacher"

    def is_assistant(self) -> bool:
        return self.role == "assistant"

    def get_id(self):
        return self.student_id

    def get_email(self):
        return self.email


class Teacher(db.Model):
    __tablename__ = 'teachers'

    teacher_id = db.Column(db.String(20), primary_key=True, nullable=False)
    name = db.Column(db.String(64), nullable=False)
    password = db.Column(db.String(150), nullable=False)
    college = db.Column(db.String(64), nullable=False)

    def __init__(self, teacher_id, name, password, college):
        self.teacher_id = teacher_id
        self.name = name
        self.password = password
        self.college = college

    def set_password(self, password):
        self.password = password

    def set_name(self, name):
        self.name = name

    def set_college(self, college):
        self.college = college

    # Relationships
    #courses = relationship('Course', backref='teacher', lazy=True)
    corrections = relationship('CorrectionRecord', backref='teacher', lazy=True)
    notices = relationship('CourseNotice', backref='teacher', lazy=True)


class Course(db.Model):
    __tablename__ = 'courses'

    course_id = db.Column(db.String(64), primary_key=True, nullable=False)  # 主键
    course_sequence = db.Column(db.Integer, nullable=False)  # 课程顺序
    course_name = db.Column(db.String(64), nullable=False)  # 课程名称
    introduction = db.Column(db.String(64), nullable=True)
    syllabus = db.Column(db.String(500), nullable=True)

    # Relationships
    homeworks = relationship('Homework', backref='course', lazy=True)
    exams = relationship('Exam', backref='course', lazy=True)
    groups = relationship('Group', backref='course', lazy=True)


class Homework(db.Model):
    __tablename__ = 'homeworks'

    homework_id = db.Column(db.Integer, primary_key=True, nullable=False, autoincrement=True)
    title = db.Column(db.String(64), nullable=False)
    homework_description = db.Column(db.Text, nullable=False)
    start_time = db.Column(db.DateTime, nullable=False)
    end_time = db.Column(db.DateTime, nullable=True)
    course_id = db.Column(db.String(64), db.ForeignKey('courses.course_id'), nullable=False)  # 外键
    attachment = db.Column(db.JSON, nullable=True)
    status = db.Column(db.Boolean, nullable=False)
    file_path = db.Column(db.String(150), nullable=True)
    total_score = db.Column(db.Integer, nullable=True)  # 新增字段，作业总分

    def __init__(self, title, homework_description, start_time, end_time, course_id, status, file_path, total_score):
        self.title = title
        self.homework_description = homework_description
        self.start_time = start_time
        self.end_time = end_time
        self.course_id = course_id
        self.status = status
        self.file_path = file_path
        self.total_score = total_score

    def set_status(self, status):
        self.status = status

    def set_attachment(self, attachment):
        self.attachment = attachment

    # Relationships
    submissions = relationship('SubmissionHomework', backref='homework', lazy=True)


class SubmissionResource(db.Model):
    __tablename__ = 'submission_resource'

    submissionR_id = db.Column(db.Integer, primary_key=True, nullable=False, autoincrement=True)
    course_id = db.Column(db.String(64), db.ForeignKey('courses.course_id'), nullable=False)
    teacher_id = db.Column(db.String(20), db.ForeignKey('teachers.teacher_id'), nullable=False)
    submission_time = db.Column(db.DateTime, nullable=False)
    file_path = db.Column(db.String(150), nullable=True)

    def __init__(self, course_id, teacher_id, file_path):
        self.course_id = course_id
        self.teacher_id = teacher_id
        self.submission_time = datetime.now()
        self.file_path = file_path

    def __repr__(self):
        return '<SubmissionResource %r>' % self.submission_id


class SubmissionHomework(db.Model):
    __tablename__ = 'submission_homework'

    submissionH_id = db.Column(db.Integer, primary_key=True, nullable=False, autoincrement=True)
    student_id = db.Column(db.String(20), db.ForeignKey('users.student_id'), nullable=False)
    homework_id = db.Column(db.Integer, db.ForeignKey('homeworks.homework_id', ondelete='CASCADE'), nullable=False)
    submission_time = db.Column(db.DateTime, nullable=True)
    homework_text = db.Column(db.Text, nullable=True)
    file_path = db.Column(db.String(150), nullable=True)
    allow_delete = db.Column(db.Boolean, nullable=False, default=True)
    grade = db.Column(db.Integer, nullable=False, default=0)
    status = db.Column(db.Boolean, nullable=False)

    def __init__(self, student_id, homework_id, file_path, status):
        self.student_id = student_id
        self.homework_id = homework_id
        self.submission_time = datetime.now()
        self.file_path = file_path
        self.allow_delete = True
        self.status = status
        self.homework_text = "empty"

    def set_allow_delete(self, allow_delete):
        self.allow_delete = allow_delete

    def set_grade(self, grade):
        self.grade = grade

    def set_status(self, status):
        self.status = status

    def set_homework_text(self, homework_text):
        self.homework_text = homework_text

    def __repr__(self):
        return '<SubmissionHomework %r>' % self.submissionH_id


class CorrectionRecord(db.Model):
    __tablename__ = 'correction_records'

    correct_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    submission_id = db.Column(db.Integer, db.ForeignKey('submission_homework.submissionH_id'), nullable=False)
    teacher_id = db.Column(db.String(20), db.ForeignKey('teachers.teacher_id'), nullable=False)
    correct_condition = db.Column(db.String(64), nullable=False)
    correct_content = db.Column(db.Text, nullable=False)
    correct_date = db.Column(db.DateTime, nullable=False)


class Exam(db.Model):
    __tablename__ = 'exams'

    test_id = db.Column(db.Integer, primary_key=True, nullable=False, autoincrement=True)
    test_title = db.Column(db.String(64), nullable=False)
    test_content = db.Column(db.Text, nullable=True)
    start_time = db.Column(db.DateTime, nullable=False)
    end_time = db.Column(db.DateTime, nullable=True)
    course_id = db.Column(db.String(64), ForeignKey('courses.course_id'), nullable=False)
    total_grade = db.Column(db.Integer, nullable=False)

    def __init__(self, test_title, start_time, end_time, course_id, total_grade):
        self.test_title = test_title
        self.start_time = start_time
        self.end_time = end_time
        self.course_id = course_id
        self.total_grade = total_grade

    def set_total_grade(self, total_grade):
        self.total_grade = total_grade

    # Relationships
    exam_records = relationship('ExamRecord', backref='exam', lazy=True)


class Question(db.Model):
    __tablename__ = 'questions'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    exam_id = db.Column(db.Integer, db.ForeignKey('exams.test_id'), nullable=False)
    q_type = db.Column(db.String(20), nullable=False)  # e.g., 'multiple_choice', 'true_false', 'short_answer'
    content = db.Column(db.Text, nullable=False)  # 题目内容
    options = db.Column(db.JSON, nullable=True)  # 选项，适用于选择题
    correct_answer = db.Column(db.Text, nullable=True)  # 正确答案，适用于选择题和简答题
    score = db.Column(db.Float, nullable=False)

    exam = db.relationship('Exam', backref='questions', lazy=True)

    def __init__(self, exam_id, q_type, content, options=None, correct_answer=None, score=0):
        self.exam_id = exam_id
        self.q_type = q_type
        self.content = content
        self.options = options
        self.correct_answer = correct_answer
        self.score = score


class ExamRecord(db.Model):
    __tablename__ = 'exam_records'

    record_id = db.Column(db.Integer, primary_key=True, nullable=False)
    student_id = db.Column(db.String(20), ForeignKey('users.student_id'), nullable=False)
    test_id = db.Column(db.Integer, ForeignKey('exams.test_id'), nullable=False)
    correct_condition = db.Column(db.String(64), nullable=False)
    score = db.Column(db.Integer, nullable=False)

    def __init__(self, student_id, test_id, correct_condition, score):
        self.student_id = student_id
        self.test_id = test_id
        self.correct_condition = correct_condition
        self.score = score


class Group(db.Model):
    __tablename__ = 'groups'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    group_id = db.Column(db.Integer, nullable=False)
    course_id = db.Column(db.String(64), ForeignKey('courses.course_id'), nullable=False)
    student_id = db.Column(db.String(20), ForeignKey('users.student_id'), nullable=False)

    def __init__(self, course_id, student_id, group_id):
        self.course_id = course_id
        self.student_id = student_id
        self.group_id = group_id

    def __repr__(self):
        return '<Group %r>' % self.group_id


class CourseNotice(db.Model):
    __tablename__ = 'course_notices'

    notice_id = db.Column(db.Integer, primary_key=True, nullable=False)
    teacher_id = db.Column(db.String(20), ForeignKey('teachers.teacher_id'), nullable=False)
    notice_title = db.Column(db.String(100), nullable=True)
    notice_content = db.Column(db.Text, nullable=False)
    notice_time = db.Column(db.DateTime, nullable=True)
    course_id = db.Column(db.String(64), ForeignKey('courses.course_id'), nullable=False)

    def __init__(self, teacher_id, notice_title, notice_content, course_id, notice_time):
        self.teacher_id = teacher_id
        self.notice_title = notice_title
        self.notice_content = notice_content
        self.course_id = course_id
        self.notice_time = notice_time


class AIChat(db.Model):
    __tablename__ = 'ai_chats'

    conversation_id = db.Column(db.Integer, primary_key=True, nullable=False)
    student_id = db.Column(db.String(20), ForeignKey('users.student_id'), nullable=False)
    conversation_content = db.Column(db.Text, nullable=False)
    conversation_time = db.Column(db.DateTime, nullable=False)


class StudentCourse(db.Model):
    __tablename__ = 'student_courses'
    __table_args__ = {'extend_existing': True}

    student_id = db.Column(db.String(20), ForeignKey('users.student_id'), primary_key=True, nullable=False)
    course_id = db.Column(db.String(64), ForeignKey('courses.course_id'), primary_key=True, nullable=False)
    mark = db.Column(db.String(64), nullable=True)
    group = db.Column(db.Integer, nullable=True)
    term = db.Column(db.String(64), nullable=True)



class TeacherCourse(db.Model):
    __tablename__ = 'teacher_courses'

    course_id = db.Column(db.String(64), ForeignKey('courses.course_id'), primary_key=True, nullable=False)
    teacher_id = db.Column(db.String(20), ForeignKey('teachers.teacher_id'), primary_key=True, nullable=False)
    role = db.Column(db.String(64), nullable=False)
    term = db.Column(db.String(64), nullable=False)


class StudentExam(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    student_id = db.Column(db.Integer, nullable=False)
    exam_id = db.Column(db.Integer, db.ForeignKey('exams.test_id'))  # Fix the reference here
    # TODO json
    answers = db.Column(db.JSON)  # Stores multiple-choice answers as JSON text
    short_answers = db.Column(db.JSON, nullable=True)  # 新增字段，用于存储简答题答案
    image_path = db.Column(db.String(200))  # Path to uploaded image for large questions
    submission_date = db.Column(db.DateTime, default=datetime.utcnow)

    def __init__(self, student_id, exam_id, answers, short_answers, submission_date):
        self.student_id = student_id
        self.exam_id = exam_id
        self.answers = answers
        self.short_answers = short_answers
        self.submission_date = submission_date


class StudentCourseNotice(db.Model):
    __tablename__ = 'student_course_notices'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    student_id = db.Column(db.String(20), ForeignKey('users.student_id'), nullable=False)
    notice_id = db.Column(db.Integer, ForeignKey('course_notices.notice_id'), nullable=False)
    is_read = db.Column(db.Boolean, nullable=False, default=False)
    read_time = db.Column(db.DateTime, nullable=True)

    def __init__(self, student_id, notice_id, is_read, read_time):
        self.student_id = student_id
        self.notice_id = notice_id
        self.is_read = is_read
        self.read_time = read_time

    student = db.relationship('User', backref='read_notices', lazy=True)
    notice = db.relationship('CourseNotice', backref='read_by_students', lazy=True)


class DiscussionPost(db.Model):
    __tablename__ = 'discussion_posts'

    post_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    course_id = db.Column(db.String(64), db.ForeignKey('courses.course_id'), nullable=False)
    student_id = db.Column(db.String(20), nullable=False)
    content = db.Column(db.Text, nullable=False)  # 评论内容
    post_time = db.Column(db.DateTime, default=datetime.utcnow)  # 评论时间

    # Relationships
    replies = relationship('DiscussionReply', backref='post', lazy=True)

    def __init__(self, course_id, student_id, content):
        self.course_id = course_id
        self.student_id = student_id
        self.content = content


class DiscussionReply(db.Model):
    __tablename__ = 'discussion_replies'

    reply_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    post_id = db.Column(db.Integer, db.ForeignKey('discussion_posts.post_id'), nullable=False)  # 外键关联评论
    student_id = db.Column(db.String(20), nullable=False)
    content = db.Column(db.Text, nullable=False)  # 回复内容
    reply_time = db.Column(db.DateTime, default=datetime.utcnow)  # 回复时间

    def __init__(self, post_id, student_id, content):
        self.post_id = post_id
        self.student_id = student_id
        self.content = content
